package routers

import (
	"errors"
)

type RouterId uint

type Template [][]RouterId

type Envelope struct {
	Dest    RouterId
	Hops    uint
	Message interface{}
}

type Shutdown struct{}

func sendMessage(channel chan<- interface{}, message interface{}) (err error) {
	defer func() {
		if recover() != nil {
			err = errors.New("attempted to send on a closed channel")
		}
	}()
	channel <- message
	return
}

func MakeRouters(t Template) (in []chan<- interface{}, out <-chan Envelope) {
	channels := make([]chan interface{}, len(t))
	framework := make(chan Envelope)

	in = make([]chan<- interface{}, len(t))
	for i := range channels {
		channels[i] = make(chan interface{})
		in[i] = channels[i]
	}
	out = framework

	for routerId, neighbourIds := range t {
		neighbours := make(map[RouterId]chan<- interface{})
		for _, id := range neighbourIds {
			neighbours[id] = channels[id]
		}

		go Router(RouterId(routerId), channels[routerId], neighbours, framework, uint64(len(t)))
	}
	return
}
